#include <QtCore/QCoreApplication>
#include "PBCVC.h"
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <QDebug>
#include <sys/types.h>
#include <time.h>
#include <QTextCodec>


enum{length = 313 * sizeof(unsigned char)};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
	QTextCodec::setCodecForTr(   QTextCodec::codecForName("GB2312")   );

#ifndef myTest
	unsigned char *priR1 = (unsigned char*)malloc(length);
	unsigned char *priX1 = (unsigned char*)malloc(length);
	unsigned char *priO1 = (unsigned char*)malloc(length);

	unsigned char *pubR1 = (unsigned char*)malloc(length);
	unsigned char *pubO12 = (unsigned char*)malloc(length);
	unsigned char *pubO13 = (unsigned char*)malloc(length);
	unsigned char *pubA1 = (unsigned char*)malloc(length);
	unsigned char *pubH1 = (unsigned char*)malloc(length);

	unsigned char *cipher11 = (unsigned char*)malloc(length);
	unsigned char *cipher12 = (unsigned char*)malloc(length);
	unsigned char *cipher13 = (unsigned char*)malloc(length);
	unsigned char *plain1 = (unsigned char*)malloc(length);
	unsigned char *decryptKey1 = (unsigned char*)malloc(length);
	int len1= 0;

	unsigned char *priR2 = (unsigned char*)malloc(length);
	unsigned char *priX2 = (unsigned char*)malloc(length);
	unsigned char *priO2 = (unsigned char*)malloc(length);

	unsigned char *pubR2 = (unsigned char*)malloc(length);
	unsigned char *pubO21 = (unsigned char*)malloc(length);
	unsigned char *pubO23 = (unsigned char*)malloc(length);
	unsigned char *pubA2 = (unsigned char*)malloc(length);
	unsigned char *pubH2 = (unsigned char*)malloc(length);

	unsigned char *cipher21 = (unsigned char*)malloc(length);
	unsigned char *cipher22 = (unsigned char*)malloc(length);
	unsigned char *cipher23 = (unsigned char*)malloc(length);
	unsigned char *plain2 = (unsigned char*)malloc(length);
	unsigned char *decryptKey2 = (unsigned char*)malloc(length);
	int len2= 0;

	unsigned char *priR3 = (unsigned char*)malloc(length);
	unsigned char *priX3 = (unsigned char*)malloc(length);
	unsigned char *priO3 = (unsigned char*)malloc(length);

	unsigned char *pubR3 = (unsigned char*)malloc(length);
	unsigned char *pubO31 = (unsigned char*)malloc(length);
	unsigned char *pubO32 = (unsigned char*)malloc(length);
	unsigned char *pubA3 = (unsigned char*)malloc(length);
	unsigned char *pubH3 = (unsigned char*)malloc(length);

	unsigned char *cipher31 = (unsigned char*)malloc(length);
	unsigned char *cipher32 = (unsigned char*)malloc(length);
	unsigned char *cipher33 = (unsigned char*)malloc(length);
	unsigned char *plain3 = (unsigned char*)malloc(length);
	unsigned char *decryptKey3 = (unsigned char*)malloc(length);
	int len3= 0;

	unsigned char *groupPubR = (unsigned char*)malloc(length);
	unsigned char *groupPubA = (unsigned char*)malloc(length);
	unsigned char *generator = (unsigned char*)malloc(length);
	unsigned char *aesKey = (unsigned char*)malloc(length);

	int i = 0;
	int n;
	clock_t start, end;
	clock_t allStart,allEnd;
	double time,allTime;
	int fh;
	fh =  _open( "data.txt",  _O_APPEND|_O_WRONLY|_O_CREAT, _S_IREAD | _S_IWRITE  );

	qDebug("people\tsk and pk\tothers' pk O\tdecryptkey\tgroup key\tge-en-de key\twhole time", (double)(end - start) / CLK_TCK);
	_write(fh,"people\tsk and pk\tothers' pk O\tdecryptkey\tgroup key\tge-en-de key\twhole time\n",sizeof("people\tsk and pk\tothers' pk O\tdecryptkey\tgroup key\tge-en-de key\twhole time"));

	for ( n = 7;n != 300; n = n+6)
	{
		strcpy((char*)generator,"[6322069030959797239974302728815258316709002424839598348999808636855120175466090008089069870442189980465884571393312767672877644162824787053897296527046511, 2160399843694700352574210733609801044755127137866597903735353473997504189822218028062346910851264365516731536283788623762281392086125022828651245680060444]");

		generatePubKey(priR1,priX1,priO1,pubR1,pubA1,pubH1,length,&len1,generator);
		generatePubKey(priR2,priX2,priO2,pubR2,pubA2,pubH2,length,&len2,generator);

		printf("%d\t",n);

		start = clock();
		allStart = clock();

		generatePubKey(priR3,priX3,priO3,pubR3,pubA3,pubH3,length,&len3,generator);

		end = clock();
		time = (float)(end - start) / CLK_TCK;
		//qDebug("The time of generate public and security Key is: %f", (double)(end - start) / CLK_TCK);
		printf("%f\t", time);
		//_write(fh,&time,sizeof(time));

		i = 0;
		start = clock();
		while ( i != (n-1)/6)
		{
			computeOtherO(priX2,pubH1,priR2,length,pubO21);
			computeOtherO(priX3,pubH1,priR3,length,pubO31);

			computeOtherO(priX1,pubH2,priR1,length,pubO12);
			computeOtherO(priX3,pubH2,priR3,length,pubO32);

			computeOtherO(priX1,pubH3,priR1,length,pubO13);
			computeOtherO(priX2,pubH3,priR2,length,pubO23);
			i++;
		}
		end = clock();
		//qDebug("The time of compute Other's public key O is: %f", (double)(end - start) / CLK_TCK);
		printf("%f\t", (double)(end - start) / CLK_TCK);

		i = 0;
		start = clock();
		while ( i != (n-1)/6)
		{
			computeDecryptKey(priO1,pubO21,decryptKey1,length);
			computeDecryptKey(decryptKey1,pubO31,decryptKey1,length);

			computeDecryptKey(priO2,pubO12,decryptKey2,length);
			computeDecryptKey(decryptKey2,pubO32,decryptKey2,length);

			computeDecryptKey(priO3,pubO13,decryptKey3,length);
			computeDecryptKey(decryptKey3,pubO23,decryptKey3,length);

			i++;
		}
		end = clock();
//		qDebug("The time of compute decrypt key is: %f", (double)(end - start) / CLK_TCK);
		printf("%f\t", (double)(end - start) / CLK_TCK);


		start = clock();
		i = 0;
		while( i != (n-1)/2 )
		{
			generateGroupPubKey(pubR1,pubR2,groupPubR,length,0);
			generateGroupPubKey(groupPubR,pubR3,groupPubR,length,0);

			generateGroupPubKey(pubA1,pubA2,groupPubA,length,1);
			generateGroupPubKey(groupPubA,pubA3,groupPubA,length,1);

			i++;
		}
		end = clock();
//		qDebug("The time of generate group public key is: %f", (double)(end - start) / CLK_TCK);
		printf("%f\t", (double)(end - start) / CLK_TCK);


		start = clock();
		generateAESKey(aesKey,length);
		encryption(cipher11,cipher12,cipher13,groupPubR,groupPubA,aesKey,generator,length);

		decryption(cipher11,cipher12,cipher13,decryptKey1,pubH1,plain1,length);
		end = clock();
		allEnd = clock();
		//qDebug("The time of generate AES key and en-decryption is: %f", (double)(end - start) / CLK_TCK);
		//qDebug("The time of whole cource is: %f", (double)(allEnd - allStart) / CLK_TCK);
		printf("%f\t", (double)(end - start) / CLK_TCK);
		printf("%f\t", (double)(allEnd - allStart) / CLK_TCK);
		printf("\n");

		//qDebug("plain1 = %s\n\n",plain1);

		//		end = clock();
		//		qDebug("The time was: %f", (double)(end - start) / CLK_TCK);
		//qDebug("end");

		//decryption(cipher11,cipher12,cipher13,decryptKey2,pubH2,plain2,length);
		//qDebug("plain2 = %s\n\n",plain2);


		//decryption(cipher11,cipher12,cipher13,decryptKey3,pubH3,plain3,length);
		//qDebug("plain3 = %s\n\n",plain3);
	}

#else
	testA();

#endif

	free(priR1);
	free(priX1);
	free(priO1);
	free(pubR1);
	free(pubO12);
	free(pubO13);
	free(pubA1);
	free(pubH1);
	free(cipher11);
	free(cipher12);
	free(cipher13);
	free(plain1);
	free(decryptKey1);

	free(priR2);
	free(priX2);
	free(priO2);
	free(pubR2);
	free(pubO21);
	free(pubO23);
	free(pubA2);
	free(pubH2);
	free(cipher21 );
	free(cipher22 );
	free(cipher23);
	free(plain2);
	free(decryptKey2);

	free(priR3 );
	free(priX3 );
	free(priO3);
	free(pubR3);
	free(pubO31);
	free(pubO32);
	free(pubA3);
	free(pubH3);
	free(cipher31);
	free(cipher32);
	free(cipher33);
	free(plain3);
	free(decryptKey3);

	free(groupPubR);
	free(groupPubA);
	free(generator);

    return a.exec();
}
